﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//Salty: 鼠标检测
public class MouseController : MonoBehaviour
{
    public static MouseController Instance
    {
        get
        {
            if(_Instance == null)
            {
                _Instance = FindObjectOfType<MouseController>();
            }
            if(!_Instance)
            {
                GameObject obj = new GameObject("MouseController");
                _Instance = obj.AddComponent<MouseController>();
            }
            return _Instance;
        }
        set
        {
        
        }
    }
    private static MouseController _Instance;

    enum MouseState
    {
        Normal, Constructing, Dismantling
    }

    MouseState state = MouseState.Normal;

    RaycastHit2D[] m_HitInfo;
    Ray m_MouseRay;

    //检测点击
    private Ray ray;
    private RaycastHit2D[] hit;

    //放置物的指示器Prefab（后期应该改为数组）（装载不同塔）
    public List<GameObject> indicatorPrefab;

    //目前鼠标跟随的放置物（动态生成）
    GameObject indicatorObject;
    GameObject sightObject;
    GameObject constructing, dismantling;
    Vector3 mousePos;

    // Start is called before the first frame update
    void Start()
    {
        sightObject = Instantiate(indicatorPrefab[1], Vector3.zero, Quaternion.identity);
        constructing = Instantiate(indicatorPrefab[0], Vector3.zero, Quaternion.identity);
        constructing.SetActive(false);
        dismantling = Instantiate(indicatorPrefab[2], Vector3.zero, Quaternion.identity);
        dismantling.SetActive(false);
    }

    public void SetSightPosition(float x, float y)
    {
        Vector3 sightObjectPostion = Vector3.zero;
        sightObjectPostion.x = (float)System.Math.Round(x / ConstOfMap.xGap) * ConstOfMap.xGap;
        sightObjectPostion.y = (float)System.Math.Round(y / ConstOfMap.yGap) * ConstOfMap.yGap;
        sightObjectPostion.z = -5;
        sightObject.transform.position = sightObjectPostion;
    }

    public void SetSightPosition(Vector2 pos)
    {
        SetSightPosition(pos.x, pos.y);
    }

    // Update is called once per frame
    void Update()
    {
        if (Tag.playerPause)
            return;
        /*
        if (Input.GetKeyDown(KeyCode.KeypadEnter))
        {
            SoldierManager.Instance.CreateSoldier(0);
        }
        */
        Vector3 mouseWorldPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.position.z);
        showOutline(mouseWorldPos);
        if (mouseWorldPos != mousePos || Input.GetMouseButtonDown(0))
        {
            mousePos = mouseWorldPos;
            mouseWorldPos = Camera.main.ScreenToWorldPoint(mouseWorldPos);
            SetSightPosition(mouseWorldPos.x, mouseWorldPos.y);
        }

        Block s = GetHitBlock();
        Vector2 LD;
        Vector2 RU;

        if (Input.GetMouseButtonDown(0))
        {
            bool hitOn = false;
            ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            hit = Physics2D.RaycastAll(new Vector2(ray.origin.x, ray.origin.y), Vector2.zero);
            if (hit != null)
            {
                for (int i = 0; i < hit.Length; i++)
                {
                    if (hit[i].collider.gameObject.GetComponent<BattleObject>() != null && hit[i].collider.gameObject.GetComponent<HitPoint>() != null)
                    {
                        hitOn = true;
                        StatusBar.Instance.SetTarget(hit[i].collider.gameObject);//更新状态栏
                        break;
                    }
                }
            }
            if (!hitOn)
            {
                StatusBar.Instance.SetTarget();//状态栏显示玩家
            }
        }
        if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
        {
            if (s != null)
            {
                LD = new Vector3(s.transform.position.x - ConstOfMap.xGap / 2, s.transform.position.y - ConstOfMap.yGap / 2);
                RU = new Vector3(s.transform.position.x + ConstOfMap.xGap / 2, s.transform.position.y + ConstOfMap.yGap / 2);
                if (MapManager.Instance.IsEmpty(Function.WorldPosToLogicPos(sightObject.transform.position)))
                {
                    if (MapManager.Instance.PlayerDistance(s.pos) <= ConstOfMap.operateRange &&
                        Physics2D.OverlapArea(LD, RU, LayerMask.GetMask("Enemy", "Player")) == null)
                    {
                        Input.ResetInputAxes();
                        //Debug.Log("Instantiate tower");
                        UIManager.Instance.PushPanel("ConstructionPanel", Camera.main.WorldToScreenPoint(s.transform.localPosition));
                    }
                }
                else if (Physics2D.OverlapArea(LD, RU, LayerMask.GetMask("Enemy", "Player")) == null &&
                         MapManager.Instance.PlayerDistance(s.pos) <= ConstOfMap.operateRange)
                {
                    s.Hit();
                }
            }
        }
            

        
     
        /*
        switch (state)
        {
            case MouseState.Normal:
                if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
                {
                    if (s != null)
                    {
                        LD = new Vector3(s.transform.position.x - ConstOfMap.xGap / 2, s.transform.position.y - ConstOfMap.yGap / 2);
                        RU = new Vector3(s.transform.position.x + ConstOfMap.xGap / 2, s.transform.position.y + ConstOfMap.yGap / 2);
                        if (MapManager.Instance.PlayerDistance(s.pos) <= ConstOfMap.operateRange &&
                            Physics2D.OverlapArea(LD, RU, LayerMask.GetMask("Enemy", "Player")) == null)
                        {
                            s.Hit();
                        }
                    }
                }
                if(Input.GetKeyDown(KeyCode.Alpha1))
                {
                    //Debug.Log("aaaa");
                    state = MouseState.Constructing;
                    indicatorObject = constructing;
                    indicatorObject.SetActive(true);
                }
                else if(Input.GetKeyDown(KeyCode.Alpha2))
                {
                    state = MouseState.Dismantling;
                    indicatorObject = dismantling;
                    indicatorObject.SetActive(true);
                }
                break;
            case MouseState.Constructing:
                if (indicatorObject != null)
                {
                    if (s != null)
                    {
                        LD = new Vector3(s.transform.position.x - ConstOfMap.xGap / 2, s.transform.position.y - ConstOfMap.yGap / 2);
                        RU = new Vector3(s.transform.position.x + ConstOfMap.xGap / 2, s.transform.position.y + ConstOfMap.yGap / 2);
                        indicatorObject.transform.position = new Vector3(s.transform.position.x, s.transform.position.y, -1);
                        if (!MapManager.Instance.IsEmpty(Function.WorldPosToLogicPos(indicatorObject.transform.position)) ||
                            MapManager.Instance.PlayerDistance(s.pos) > ConstOfMap.operateRange ||
                            Physics2D.OverlapArea(LD, RU, LayerMask.GetMask("Enemy", "Player")) != null)
                        {
                            indicatorObject.GetComponent<SpriteRenderer>().color = new Color(255, 0, 0, 0.5f);
                            //Debug.LogError("red");
                        }
                        else
                        {
                            indicatorObject.GetComponent<SpriteRenderer>().color = new Color(0, 255, 0, 0.5f);
                            //如果可放置
                            if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
                            {
                                Input.ResetInputAxes();
                                Debug.Log("Instantiate tower");
                                indicatorObject.SetActive(false);
                                indicatorObject = null;
                                UIManager.Instance.PushPanel("ConstructionPanel", Camera.main.WorldToScreenPoint(s.transform.localPosition));
                                state = MouseState.Normal;
                            }
                        }
                    }
                    if(Input.GetKeyDown(KeyCode.Alpha1))
                    {
                        state = MouseState.Normal;
                        indicatorObject.SetActive(false);
                        indicatorObject = null;
                    }
                    else if(Input.GetKeyDown(KeyCode.Alpha2))
                    {
                        state = MouseState.Dismantling;
                        indicatorObject.SetActive(false);
                        indicatorObject = dismantling;
                        indicatorObject.SetActive(true);
                    }
                }
                break;
            case MouseState.Dismantling:
                if (indicatorObject != null)
                {
                    if (s != null)
                    {
                        LD = new Vector3(s.transform.position.x - ConstOfMap.xGap / 2, s.transform.position.y - ConstOfMap.yGap / 2);
                        RU = new Vector3(s.transform.position.x + ConstOfMap.xGap / 2, s.transform.position.y + ConstOfMap.yGap / 2);
                        indicatorObject.transform.position = new Vector3(s.transform.position.x, s.transform.position.y, -1);
                        if (!MapManager.Instance.IsTower(Function.WorldPosToLogicPos(indicatorObject.transform.position)) ||
                            MapManager.Instance.PlayerDistance(s.pos) > ConstOfMap.operateRange)
                        {
                            indicatorObject.GetComponent<SpriteRenderer>().color = new Color(255, 0, 0, 0.5f);
                        }
                        else
                        {
                            indicatorObject.GetComponent<SpriteRenderer>().color = new Color(0, 255, 0, 0.5f);
                            if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space))
                            {
                                Input.ResetInputAxes();
                                Debug.Log("Dismantling tower");
                                indicatorObject.SetActive(false);
                                indicatorObject = null;
                                s.Dismantle();
                                state = MouseState.Normal;
                            }
                        }
                    }
                    if (Input.GetKeyDown(KeyCode.Alpha1))
                    {
                        state = MouseState.Constructing;
                        indicatorObject.SetActive(false);
                        indicatorObject = constructing;
                        indicatorObject.SetActive(true);
                    }
                    else if (Input.GetKeyDown(KeyCode.Alpha2))
                    {
                        state = MouseState.Normal;
                        indicatorObject.SetActive(false);
                        indicatorObject = null;
                    }
                }
                break;
        }*/
        
    }
    //进行射线判断并返回射中的SquareView信息
    public Block GetHitBlock()
    {
        Vector2 startPos = new Vector2(sightObject.transform.position.x, sightObject.transform.position.y);
        m_HitInfo = Physics2D.RaycastAll(startPos, Vector2.zero);
        if (m_HitInfo != null)
        {
            for(int i = 0; i < m_HitInfo.Length; i++)
            {
                if (m_HitInfo[i].collider.gameObject.CompareTag("Block"))
                {
                    return m_HitInfo[i].collider.GetComponent<Block>();
                }
            }
        }
        return null;
    }

    public void showOutline(Vector3 mousePos)
    {
        mousePos = Camera.main.ScreenToWorldPoint(mousePos);
        RaycastHit2D[] hitInfos = Physics2D.RaycastAll(mousePos, new Vector3(0, 0, 1), 100, LayerMask.GetMask("Enemy", "Player", "Tower"));

        if (hitInfos != null)
        {
            for(int i = 0; i < hitInfos.Length; i++)
            {
                GameObject obj = (GameObject)hitInfos[i].collider.gameObject;
                BodyColor outline = obj.GetComponentInChildren<BodyColor>();
                if (outline != null)
                {
                    outline.wantShow = true;
                }
            }    
        }
    }
}
